package cn.highedu.coolshark.product.service.impl;

import cn.highedu.coolshark.common.*;
import cn.highedu.coolshark.product.mapper.CategoryMapper;
import cn.highedu.coolshark.product.pojo.dto.CategoryAddNewDTO;
import cn.highedu.coolshark.product.pojo.dto.CategoryUpdateDTO;
import cn.highedu.coolshark.product.pojo.entity.Category;
import cn.highedu.coolshark.product.pojo.vo.CategoryListItemVO;
import cn.highedu.coolshark.product.pojo.vo.CategoryStandardVO;
import cn.highedu.coolshark.product.service.ICategoryService;
import cn.highedu.coolshark.common.ServiceCode;
import cn.highedu.coolshark.common.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 处理类别业务的实现类
 *
 * @author java@tedu.cn
 * @version 0.0.1
 */
@Slf4j
@Service
public class CategoryServiceImpl implements ICategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    public CategoryServiceImpl() {
        log.debug("创建业务类对象：CategoryServiceImpl");
    }

    @Override
    public void addNew(CategoryAddNewDTO categoryAddNewDTO) {
        // 调用参数对象的getName()得到尝试添加的类别的名称
        String name = categoryAddNewDTO.getName();
        // 在当前类别的父级类别下，根据名称查询类别数量，检查名称是否被占用
        int count = categoryMapper.countByNameAndParentId(name, categoryAddNewDTO.getParentId());
        log.debug("根据名称【{}】统计数量，结果：{}", name, count);
        // 判断统计结果是否大于0
        if (count > 0) {
            // 是：名称被占用，抛出异常
            String message = "添加类别失败，类别名称已经被占用！";
            log.warn(message);
            throw new EntityAlreadyExistsException(message);
        }

        // 通过参数对象获取parentId
        Long parentId = categoryAddNewDTO.getParentId();
        // 预设depth（深度值）为1
        Integer depth = 1;
        CategoryStandardVO parentCategory = null;
        // 判断parentId是否不为0
        if (parentId != 0) {
            // 否：调用Mapper对象的getStandardById()查询父级类别
            parentCategory = categoryMapper.getStandardById(parentId);
            // 判断查询结果（父级类别）是否为null
            if (parentCategory == null) {
                // 是：抛出异常
                String message = "添加类别失败，父级类别不存在！";
                log.warn(message);
                throw new EntityNotFoundException(message);
            } else {
                // 否：depth（深度值）为：父级类别的depth + 1
                depth = parentCategory.getDepth() + 1;
            }
        }

        // 创建Category对象
        Category category = new Category();
        // 复制属性
        BeanUtils.copyProperties(categoryAddNewDTO, category);
        // 补全Category对象的属性值：depth >>>
        category.setDepth(depth);
        // 补全Category对象的属性值：isParent >>> 固定为0
        category.setIsParent(0);
        // 调用Mapper对象的insert()方法执行插入
        int rows = categoryMapper.insert(category);
        if (rows != 1) {
            String message = "添加类别失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new EntitySaveFailedException(message);
        }

        // 判断parentId是否不为0，并判断父级类别的isParent是否为0
        if (parentId != 0 && parentCategory.getIsParent() == 0) {
            // 是：将父级类别的isParent更新为1
            Category updateParentCategory = new Category();
            updateParentCategory.setId(parentId);
            updateParentCategory.setIsParent(1);
            rows = categoryMapper.update(updateParentCategory);
            if (rows != 1) {
                String message = "添加类别失败，服务器忙，请稍后再尝试！";
                log.warn(message);
                throw new EntitySaveFailedException(message);
            }
        }
    }

    @Override
    public void delete(Long id) {
        log.debug("开始处理【根据ID删除类别】的业务，参数：{}", id);
        // 调用Mapper对象的getStandardById()执行查询
        CategoryStandardVO currentCategory = categoryMapper.getStandardById(id);
        // 判断查询结果是否为null，如果是，则抛出异常
        if (currentCategory == null) {
            // 是：数据不存在，抛出异常
            String message = "删除类别失败，尝试删除的类别数据不存在！";
            log.warn(message);
            throw new EntityNotFoundException(message);
        }

        // 判断查询结果中的isParent是否为1，如果是，则抛出异常
        if (currentCategory.getIsParent() == 1) {
            String message = "删除类别失败，该类别仍包含子级类别！";
            log.warn(message);
            throw new EntityIsAssociatedException(message);
        }

        // 调用Mapper对象的deleteById()方法执行删除
        int rows = categoryMapper.deleteById(id);
        if (rows != 1) {
            String message = "删除类别失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new EntityDeleteFailedException(message);
        }

        // 调用Mapper对象的countByParentId方法，根据以上查询结果中的parentId，执行统计
        Long parentId = currentCategory.getParentId();
        int count = categoryMapper.countByParentId(parentId);
        // 判断统计结果为0，则将父级类别的isParent更新为0
        if (count == 0) {
            Category parentCategory = new Category();
            parentCategory.setId(parentId);
            parentCategory.setIsParent(0);
            rows = categoryMapper.update(parentCategory);
            if (rows != 1) {
                String message = "删除类别失败，服务器忙，请稍后再尝试！";
                log.warn(message);
                throw new EntityDeleteFailedException(message);
            }
        }
    }

    @Override
    public void setEnable(Long id) {
        log.debug("开始处理【启用类别】的业务，参数：{}", id);
        updateEnableById(id, 1);
    }

    @Override
    public void setDisable(Long id) {
        log.debug("开始处理【禁用类别】的业务，参数：{}", id);
        updateEnableById(id, 0);
    }

    @Override
    public void setDisplay(Long id) {
        log.debug("开始处理【将类别显示在导航栏】的业务，参数：{}", id);
        updateDisplayById(id, 1);
    }

    @Override
    public void setHidden(Long id) {
        log.debug("开始处理【将类别不显示在导航栏】的业务，参数：{}", id);
        updateDisplayById(id, 0);
    }

    @Override
    public void updateInfoById(Long id, CategoryUpdateDTO categoryUpdateDTO) {
        log.debug("开始处理【修改类别详情】的业务，ID：{}，新数据：{}", id, categoryUpdateDTO);
        // 调用Mapper对象的getStandardById()执行查询
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        // 判断查询结果是否为null
        if (queryResult == null) {
            // 是：抛出异常
            String message = "修改类别详情失败，尝试修改的类别数据不存在！";
            log.warn(message);
            throw new EntityNotFoundException(message);
        }

        // 调用Mapper对象的countByNameAndNotId()执行统计
        int count = categoryMapper.countByNameAndNotId(id, categoryUpdateDTO.getName());
        // 判断统计结果是否大于0
        if (count > 0) {
            // 是：名称被占用，抛出异常
            String message = "修改类别详情失败，类别名称已经被占用！";
            log.warn(message);
            throw new EntityAlreadyExistsException(message);
        }

        // 创建Category对象
        Category category = new Category();
        // 复制属性，设置ID
        BeanUtils.copyProperties(categoryUpdateDTO, category);
        category.setId(id);
        // 调用Mapper对象的update()方法执行修改
        int rows = categoryMapper.update(category);
        if (rows != 1) {
            String message = "修改类别详情失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new EntityUpdateFailedException(message);
        }
    }

    @Override
    public CategoryStandardVO getStandardById(Long id) {
        log.debug("开始处理【根据ID查询类别详情】的业务，参数：{}", id);
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        if (queryResult == null) {
            // 是：抛出异常
            String message = "查询类别详情失败，类别数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        return queryResult;
    }

    @Override
    public List<CategoryListItemVO> listByParentId(Long parentId) {
        log.debug("开始处理【根据父级查询子级类别列表】的业务，参数：{}", parentId);
        List<CategoryListItemVO> list = categoryMapper.listByParentId(parentId);
        return list;
    }

    private void updateEnableById(Long id, Integer enable) {
        // 创建Category对象
        Category updateCategory = new Category();
        // 向Category对象中封装属性值：id, enable，均来自方法参数
        updateCategory.setId(id);
        updateCategory.setEnable(enable);
        // 调用Mapper对象的update()方法执行更新
        int rows = categoryMapper.update(updateCategory);
        if (rows != 1) {
            String message = ENABLE_TEXT[enable] + "类别失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new EntityUpdateFailedException(message);
        }
    }

    private void updateDisplayById(Long id, Integer isDisplay) {
        // 调用Mapper对象的getStandardById()方法执行查询
        CategoryStandardVO currentCategory = categoryMapper.getStandardById(id);
        // 判断查询结果是否为null，如果是，则抛出异常
        if (currentCategory == null) {
            String message = DISPLAY_TEXT[isDisplay] + "类别失败，类别数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 判断查询结果中的isDisplay与参数isDisplay是否相同，如果是，则抛出异常（当前状态与目标状态相同，没必要执行更新）
        if (currentCategory.getIsDisplay() == isDisplay) {
            String message = DISPLAY_TEXT[isDisplay] + "类别失败，此类别已经处于" + DISPLAY_TEXT[isDisplay] + "状态！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 创建Category对象
        Category updateCategory = new Category();
        // 向Category对象中封装属性值：id, isDisplay，均来自方法参数
        updateCategory.setId(id);
        updateCategory.setIsDisplay(isDisplay);
        // 调用Mapper对象的update()方法执行更新
        int rows = categoryMapper.update(updateCategory);
        if (rows != 1) {
            String message = DISPLAY_TEXT[isDisplay] + "类别失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new EntityUpdateFailedException(message);
        }
    }

}
